home *** CD-ROM | disk | FTP | other *** search
- Subject: v24i008: RCS source control system, Part08/12
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 03e33083 44e7b0bc b7f9d611 3c76c722
-
- Submitted-by: Adam Hammer <hammer@cs.purdue.edu>
- Posting-number: Volume 24, Issue 8
- Archive-name: rcs/part08
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: COPYING src/partime.c src/rcssyn.c
- # Wrapped by rsalz@litchi.bbn.com on Thu Feb 21 14:37:04 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 8 (of 12)."'
- if test -f 'COPYING' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'COPYING'\"
- else
- echo shar: Extracting \"'COPYING'\" \(12488 characters\)
- sed "s/^X//" >'COPYING' <<'END_OF_FILE'
- X
- X GNU GENERAL PUBLIC LICENSE
- X Version 1, February 1989
- X
- X Copyright (C) 1989 Free Software Foundation, Inc.
- X 675 Mass Ave, Cambridge, MA 02139, USA
- X Everyone is permitted to copy and distribute verbatim copies
- X of this license document, but changing it is not allowed.
- X
- X Preamble
- X
- X The license agreements of most software companies try to keep users
- Xat the mercy of those companies. By contrast, our General Public
- XLicense is intended to guarantee your freedom to share and change free
- Xsoftware--to make sure the software is free for all its users. The
- XGeneral Public License applies to the Free Software Foundation's
- Xsoftware and to any other program whose authors commit to using it.
- XYou can use it for your programs, too.
- X
- X When we speak of free software, we are referring to freedom, not
- Xprice. Specifically, the General Public License is designed to make
- Xsure that you have the freedom to give away or sell copies of free
- Xsoftware, that you receive source code or can get it if you want it,
- Xthat you can change the software or use pieces of it in new free
- Xprograms; and that you know you can do these things.
- X
- X To protect your rights, we need to make restrictions that forbid
- Xanyone to deny you these rights or to ask you to surrender the rights.
- XThese restrictions translate to certain responsibilities for you if you
- Xdistribute copies of the software, or if you modify it.
- X
- X For example, if you distribute copies of a such a program, whether
- Xgratis or for a fee, you must give the recipients all the rights that
- Xyou have. You must make sure that they, too, receive or can get the
- Xsource code. And you must tell them their rights.
- X
- X We protect your rights with two steps: (1) copyright the software, and
- X(2) offer you this license which gives you legal permission to copy,
- Xdistribute and/or modify the software.
- X
- X Also, for each author's protection and ours, we want to make certain
- Xthat everyone understands that there is no warranty for this free
- Xsoftware. If the software is modified by someone else and passed on, we
- Xwant its recipients to know that what they have is not the original, so
- Xthat any problems introduced by others will not reflect on the original
- Xauthors' reputations.
- X
- X The precise terms and conditions for copying, distribution and
- Xmodification follow.
- X
- X GNU GENERAL PUBLIC LICENSE
- X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- X
- X 0. This License Agreement applies to any program or other work which
- Xcontains a notice placed by the copyright holder saying it may be
- Xdistributed under the terms of this General Public License. The
- X"Program", below, refers to any such program or work, and a "work based
- Xon the Program" means either the Program or any work containing the
- XProgram or a portion of it, either verbatim or with modifications. Each
- Xlicensee is addressed as "you".
- X
- X 1. You may copy and distribute verbatim copies of the Program's source
- Xcode as you receive it, in any medium, provided that you conspicuously and
- Xappropriately publish on each copy an appropriate copyright notice and
- Xdisclaimer of warranty; keep intact all the notices that refer to this
- XGeneral Public License and to the absence of any warranty; and give any
- Xother recipients of the Program a copy of this General Public License
- Xalong with the Program. You may charge a fee for the physical act of
- Xtransferring a copy.
- X
- X 2. You may modify your copy or copies of the Program or any portion of
- Xit, and copy and distribute such modifications under the terms of Paragraph
- X1 above, provided that you also do the following:
- X
- X a) cause the modified files to carry prominent notices stating that
- X you changed the files and the date of any change; and
- X
- X b) cause the whole of any work that you distribute or publish, that
- X in whole or in part contains the Program or any part thereof, either
- X with or without modifications, to be licensed at no charge to all
- X third parties under the terms of this General Public License (except
- X that you may choose to grant warranty protection to some or all
- X third parties, at your option).
- X
- X c) If the modified program normally reads commands interactively when
- X run, you must cause it, when started running for such interactive use
- X in the simplest and most usual way, to print or display an
- X announcement including an appropriate copyright notice and a notice
- X that there is no warranty (or else, saying that you provide a
- X warranty) and that users may redistribute the program under these
- X conditions, and telling the user how to view a copy of this General
- X Public License.
- X
- X d) You may charge a fee for the physical act of transferring a
- X copy, and you may at your option offer warranty protection in
- X exchange for a fee.
- X
- XMere aggregation of another independent work with the Program (or its
- Xderivative) on a volume of a storage or distribution medium does not bring
- Xthe other work under the scope of these terms.
- X
- X 3. You may copy and distribute the Program (or a portion or derivative of
- Xit, under Paragraph 2) in object code or executable form under the terms of
- XParagraphs 1 and 2 above provided that you also do one of the following:
- X
- X a) accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X b) accompany it with a written offer, valid for at least three
- X years, to give any third party free (except for a nominal charge
- X for the cost of distribution) a complete machine-readable copy of the
- X corresponding source code, to be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X c) accompany it with the information you received as to where the
- X corresponding source code may be obtained. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form alone.)
- X
- XSource code for a work means the preferred form of the work for making
- Xmodifications to it. For an executable file, complete source code means
- Xall the source code for all modules it contains; but, as a special
- Xexception, it need not include source code for modules which are standard
- Xlibraries that accompany the operating system on which the executable
- Xfile runs, or for standard header files or definitions files that
- Xaccompany that operating system.
- X
- X 4. You may not copy, modify, sublicense, distribute or transfer the
- XProgram except as expressly provided under this General Public License.
- XAny attempt otherwise to copy, modify, sublicense, distribute or transfer
- Xthe Program is void, and will automatically terminate your rights to use
- Xthe Program under this License. However, parties who have received
- Xcopies, or rights to use copies, from you under this General Public
- XLicense will not have their licenses terminated so long as such parties
- Xremain in full compliance.
- X
- X 5. By copying, distributing or modifying the Program (or any work based
- Xon the Program) you indicate your acceptance of this license to do so,
- Xand all its terms and conditions.
- X
- X 6. Each time you redistribute the Program (or any work based on the
- XProgram), the recipient automatically receives a license from the original
- Xlicensor to copy, distribute or modify the Program subject to these
- Xterms and conditions. You may not impose any further restrictions on the
- Xrecipients' exercise of the rights granted herein.
- X
- X 7. The Free Software Foundation may publish revised and/or new versions
- Xof the General Public License from time to time. Such new versions will
- Xbe similar in spirit to the present version, but may differ in detail to
- Xaddress new problems or concerns.
- X
- XEach version is given a distinguishing version number. If the Program
- Xspecifies a version number of the license which applies to it and "any
- Xlater version", you have the option of following the terms and conditions
- Xeither of that version or of any later version published by the Free
- XSoftware Foundation. If the Program does not specify a version number of
- Xthe license, you may choose any version ever published by the Free Software
- XFoundation.
- X
- X 8. If you wish to incorporate parts of the Program into other free
- Xprograms whose distribution conditions are different, write to the author
- Xto ask for permission. For software which is copyrighted by the Free
- XSoftware Foundation, write to the Free Software Foundation; we sometimes
- Xmake exceptions for this. Our decision will be guided by the two goals
- Xof preserving the free status of all derivatives of our free software and
- Xof promoting the sharing and reuse of software generally.
- X
- X NO WARRANTY
- X
- X 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- XOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- XPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
- XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
- XTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
- XPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
- XREPAIR OR CORRECTION.
- X
- X 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- XWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- XREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
- XINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
- XOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
- XTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
- XYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
- XPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
- XPOSSIBILITY OF SUCH DAMAGES.
- X
- X END OF TERMS AND CONDITIONS
- X
- X Appendix: How to Apply These Terms to Your New Programs
- X
- X If you develop a new program, and you want it to be of the greatest
- Xpossible use to humanity, the best way to achieve this is to make it
- Xfree software which everyone can redistribute and change under these
- Xterms.
- X
- X To do so, attach the following notices to the program. It is safest to
- Xattach them to the start of each source file to most effectively convey
- Xthe exclusion of warranty; and each file should have at least the
- X"copyright" line and a pointer to where the full notice is found.
- X
- X <one line to give the program's name and a brief idea of what it does.>
- X Copyright (C) 19yy <name of author>
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 1, or (at your option)
- X any later version.
- X
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- XAlso add information on how to contact you by electronic and paper mail.
- X
- XIf the program is interactive, make it output a short notice like this
- Xwhen it starts in an interactive mode:
- X
- X Gnomovision version 69, Copyright (C) 19xx name of author
- X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- X This is free software, and you are welcome to redistribute it
- X under certain conditions; type `show c' for details.
- X
- XThe hypothetical commands `show w' and `show c' should show the
- Xappropriate parts of the General Public License. Of course, the
- Xcommands you use may be called something other than `show w' and `show
- Xc'; they could even be mouse-clicks or menu items--whatever suits your
- Xprogram.
- X
- XYou should also get your employer (if you work as a programmer) or your
- Xschool, if any, to sign a "copyright disclaimer" for the program, if
- Xnecessary. Here a sample; alter the names:
- X
- X Yoyodyne, Inc., hereby disclaims all copyright interest in the
- X program `Gnomovision' (a program to direct compilers to make passes
- X at assemblers) written by James Hacker.
- X
- X <signature of Ty Coon>, 1 April 1989
- X Ty Coon, President of Vice
- X
- XThat's all there is to it!
- END_OF_FILE
- if test 12488 -ne `wc -c <'COPYING'`; then
- echo shar: \"'COPYING'\" unpacked with wrong size!
- fi
- # end of 'COPYING'
- fi
- if test -f 'src/partime.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/partime.c'\"
- else
- echo shar: Extracting \"'src/partime.c'\" \(19500 characters\)
- sed "s/^X//" >'src/partime.c' <<'END_OF_FILE'
- X/*
- X * PARTIME parse date/time string into a TM structure
- X *
- X * Returns:
- X * 0 if parsing failed
- X * else time values in specified TM structure and zone (unspecified values
- X * set to TMNULL)
- X * Notes:
- X * This code is quasi-public; it may be used freely in like software.
- X * It is not to be sold, nor used in licensed software without
- X * permission of the author.
- X * For everyone's benefit, please report bugs and improvements!
- X * Copyright 1980 by Ken Harrenstien, SRI International.
- X * (ARPANET: KLH @ SRI)
- X */
- X
- X/* Hacknotes:
- X * If parsing changed so that no backup needed, could perhaps modify
- X * to use a FILE input stream. Need terminator, though.
- X * Perhaps should return 0 on success, else a non-zero error val?
- X */
- X
- X/* $Log: partime.c,v $
- X * Revision 5.4 1990/10/04 06:30:15 eggert
- X * Remove date vs time heuristics that fail between 2000 and 2400.
- X * Check for overflow when lexing an integer.
- X * Parse 'Jan 10 LT' as 'Jan 10, LT', not 'Jan, 10 LT'.
- X *
- X * Revision 5.3 1990/09/24 18:56:31 eggert
- X * Update timezones.
- X *
- X * Revision 5.2 1990/09/04 08:02:16 eggert
- X * Don't parse two-digit years, because it won't work after 1999/12/31.
- X * Don't permit 'Aug Aug'.
- X *
- X * Revision 5.1 1990/08/29 07:13:49 eggert
- X * Be able to parse our own date format. Don't assume year<10000.
- X *
- X * Revision 5.0 1990/08/22 08:12:40 eggert
- X * Switch to GMT and fix the bugs exposed thereby. Update timezones.
- X * Ansify and Posixate. Fix peekahead and int-size bugs.
- X *
- X * Revision 1.4 89/05/01 14:48:46 narten
- X * fixed #ifdef DEBUG construct
- X *
- X * Revision 1.3 88/08/28 14:53:40 eggert
- X * Remove unportable "#endif XXX"s.
- X *
- X * Revision 1.2 87/03/27 14:21:53 jenkins
- X * Port to suns
- X *
- X * Revision 1.1 82/05/06 11:38:26 wft
- X * Initial revision
- X *
- X */
- X
- X#include "rcsbase.h"
- X
- XlibId(partId, "$Id: partime.c,v 5.4 1990/10/04 06:30:15 eggert Exp $")
- X
- X#define given(v) (0 <= (v))
- X#define TMNULL (-1) /* Items not given are given this value */
- X#define TZ_OFFSET (24*60) /* TMNULL < zone_offset - TZ_OFFSET */
- X
- Xstruct tmwent {
- X const char *went;
- X short wval;
- X char wflgs;
- X char wtype;
- X};
- X /* wflgs */
- X#define TWTIME 02 /* Word is a time value (absence implies date) */
- X#define TWDST 04 /* Word is a DST-type timezone */
- X /* wtype */
- X#define TM_MON 1 /* month name */
- X#define TM_WDAY 2 /* weekday name */
- X#define TM_ZON 3 /* time zone name */
- X#define TM_LT 4 /* local time */
- X#define TM_DST 5 /* daylight savings time */
- X#define TM_12 6 /* AM, PM, NOON, or MIDNIGHT */
- X /* wval (for wtype==TM_12) */
- X#define T12_AM 1
- X#define T12_PM 2
- X#define T12_NOON 12
- X#define T12_MIDNIGHT 0
- X
- Xstatic const struct tmwent tmwords [] = {
- X {"january", 0, 0, TM_MON},
- X {"february", 1, 0, TM_MON},
- X {"march", 2, 0, TM_MON},
- X {"april", 3, 0, TM_MON},
- X {"may", 4, 0, TM_MON},
- X {"june", 5, 0, TM_MON},
- X {"july", 6, 0, TM_MON},
- X {"august", 7, 0, TM_MON},
- X {"september", 8, 0, TM_MON},
- X {"october", 9, 0, TM_MON},
- X {"november", 10, 0, TM_MON},
- X {"december", 11, 0, TM_MON},
- X
- X {"sunday", 0, 0, TM_WDAY},
- X {"monday", 1, 0, TM_WDAY},
- X {"tuesday", 2, 0, TM_WDAY},
- X {"wednesday", 3, 0, TM_WDAY},
- X {"thursday", 4, 0, TM_WDAY},
- X {"friday", 5, 0, TM_WDAY},
- X {"saturday", 6, 0, TM_WDAY},
- X
- X {"gmt", 0*60, TWTIME, TM_ZON}, /* Greenwich */
- X {"utc", 0*60, TWTIME, TM_ZON},
- X {"ut", 0*60, TWTIME, TM_ZON},
- X
- X {"nzst", -12*60, TWTIME, TM_ZON}, /* New Zealand */
- X {"jst", -9*60, TWTIME, TM_ZON}, /* Japan */
- X {"kst", -9*60, TWTIME, TM_ZON}, /* Korea */
- X {"ist", -5*60-30, TWTIME, TM_ZON},/* India */
- X {"eet", -2*60, TWTIME, TM_ZON}, /* Eastern Europe */
- X {"cet", -1*60, TWTIME, TM_ZON}, /* Central Europe */
- X {"met", -1*60, TWTIME, TM_ZON}, /* Middle Europe */
- X {"wet", 0*60, TWTIME, TM_ZON}, /* Western Europe */
- X {"nst", 3*60+30, TWTIME, TM_ZON},/* Newfoundland */
- X {"ast", 4*60, TWTIME, TM_ZON}, /* Atlantic */
- X {"est", 5*60, TWTIME, TM_ZON}, /* Eastern */
- X {"cst", 6*60, TWTIME, TM_ZON}, /* Central */
- X {"mst", 7*60, TWTIME, TM_ZON}, /* Mountain */
- X {"pst", 8*60, TWTIME, TM_ZON}, /* Pacific */
- X {"akst", 9*60, TWTIME, TM_ZON}, /* Alaska */
- X {"hast", 10*60, TWTIME, TM_ZON}, /* Hawaii-Aleutian */
- X {"hst", 10*60, TWTIME, TM_ZON}, /* Hawaii */
- X {"sst", 11*60, TWTIME, TM_ZON}, /* Samoa */
- X
- X {"nzdt", -12*60, TWTIME+TWDST, TM_ZON}, /* New Zealand */
- X {"kdt", -9*60, TWTIME+TWDST, TM_ZON}, /* Korea */
- X {"bst", 0*60, TWTIME+TWDST, TM_ZON}, /* Britain */
- X {"ndt", 2*60+30, TWTIME+TWDST, TM_ZON}, /*Newfoundland (DDST)*/
- X {"adt", 4*60, TWTIME+TWDST, TM_ZON}, /* Atlantic */
- X {"edt", 5*60, TWTIME+TWDST, TM_ZON}, /* Eastern */
- X {"cdt", 6*60, TWTIME+TWDST, TM_ZON}, /* Central */
- X {"mdt", 7*60, TWTIME+TWDST, TM_ZON}, /* Mountain */
- X {"pdt", 8*60, TWTIME+TWDST, TM_ZON}, /* Pacific */
- X {"akdt", 9*60, TWTIME+TWDST, TM_ZON}, /* Alaska */
- X {"hadt", 10*60, TWTIME+TWDST, TM_ZON}, /* Hawaii-Aleutian */
- X
- X#if 0
- X /*
- X * The following names are duplicates or are not well attested.
- X * A standard is needed.
- X */
- X {"?st", -13*60, TWTIME, TM_ZON}, /* Uelen */
- X {"?st", -11*60, TWTIME, TM_ZON}, /* Magadan */
- X {"east", -10*60, TWTIME, TM_ZON}, /* Eastern Australia */
- X {"cast", -9*60-30, TWTIME, TM_ZON},/* Central Australia */
- X {"cst", -8*60, TWTIME, TM_ZON}, /* China */
- X {"hkt", -8*60, TWTIME, TM_ZON}, /* Hong Kong */
- X {"sst", -8*60, TWTIME, TM_ZON}, /* Singapore */
- X {"wast", -8*60, TWTIME, TM_ZON}, /* Western Australia */
- X {"?st", -7*60, TWTIME, TM_ZON}, /* Novosibirsk */
- X {"jt", -7*60-30, TWTIME, TM_ZON},/* Java */
- X {"nst", -6*60-30, TWTIME, TM_ZON},/* North Sumatra */
- X {"?st", -6*60, TWTIME, TM_ZON}, /* Tashkent */
- X {"?st", -5*60, TWTIME, TM_ZON}, /* Sverdlovsk */
- X {"?", -4*60-30, TWTIME, TM_ZON},/* Afghanistan */
- X {"?st", -4*60, TWTIME, TM_ZON}, /* Rostov */
- X {"it", -3*60-30, TWTIME, TM_ZON},/* Iran */
- X {"?st", -3*60, TWTIME, TM_ZON}, /* Moscow */
- X {"ist", -2*60, TWTIME, TM_ZON}, /* Israel */
- X {"ast", 1*60, TWTIME, TM_ZON}, /* Azores */
- X {"fst", 2*60, TWTIME, TM_ZON}, /* Fernando de Noronha */
- X {"bst", 3*60, TWTIME, TM_ZON}, /* Brazil */
- X {"wst", 4*60, TWTIME, TM_ZON}, /* Western Brazil */
- X {"ast", 5*60, TWTIME, TM_ZON}, /* Acre Brazil */
- X {"?", 9*60+30, TWTIME, TM_ZON},/* Marquesas */
- X {"?st", 12*60, TWTIME, TM_ZON}, /* Kwajalein */
- X
- X {"?dt", -13*60, TWTIME+TWDST, TM_ZON}, /* Uelen */
- X {"?dt", -11*60, TWTIME+TWDST, TM_ZON}, /* Magadan */
- X {"eadt", -10*60, TWTIME+TWDST, TM_ZON}, /* Eastern Australia */
- X {"cadt", -9*60-30, TWTIME+TWDST, TM_ZON}, /* Central Australia */
- X {"cdt", -8*60, TWTIME+TWDST, TM_ZON}, /* China */
- X {"wadt", -8*60, TWTIME+TWDST, TM_ZON}, /* Western Australia */
- X {"?dt", -7*60, TWTIME+TWDST, TM_ZON}, /* Novosibirsk */
- X {"?dt", -6*60, TWTIME+TWDST, TM_ZON}, /* Tashkent */
- X {"?dt", -5*60, TWTIME+TWDST, TM_ZON}, /* Sverdlovsk */
- X {"?dt", -4*60, TWTIME+TWDST, TM_ZON}, /* Rostov */
- X {"?dt", -3*60, TWTIME+TWDST, TM_ZON}, /* Moscow */
- X {"idt", -2*60, TWTIME+TWDST, TM_ZON}, /* Israel */
- X {"eest", -2*60, TWTIME+TWDST, TM_ZON}, /* Eastern Europe */
- X {"cest", -1*60, TWTIME+TWDST, TM_ZON}, /* Central Europe */
- X {"mest", -1*60, TWTIME+TWDST, TM_ZON}, /* Middle Europe */
- X {"west", 0*60, TWTIME+TWDST, TM_ZON}, /* Western Europe */
- X {"adt", 1*60, TWTIME+TWDST, TM_ZON}, /* Azores */
- X {"fdt", 2*60, TWTIME+TWDST, TM_ZON}, /* Fernando de Noronha */
- X {"edt", 3*60, TWTIME+TWDST, TM_ZON}, /* Eastern Brazil */
- X {"wdt", 4*60, TWTIME+TWDST, TM_ZON}, /* Western Brazil */
- X {"adt", 5*60, TWTIME+TWDST, TM_ZON}, /* Acre Brazil */
- X#endif
- X
- X {"lt", 0, TWTIME, TM_LT}, /* local time */
- X {"dst", 1*60, TWTIME, TM_DST}, /* daylight savings time */
- X {"ddst", 2*60, TWTIME, TM_DST}, /* double dst */
- X
- X {"am", T12_AM, TWTIME, TM_12},
- X {"pm", T12_PM, TWTIME, TM_12},
- X {"noon", T12_NOON, TWTIME, TM_12},
- X {"midnight", T12_MIDNIGHT, TWTIME, TM_12},
- X
- X {0, 0, 0, 0}, /* Zero entry to terminate searches */
- X};
- X
- Xstruct token {
- X const char *tcp;/* pointer to string */
- X int tcnt; /* # chars */
- X char tbrk; /* "break" char */
- X char tbrkl; /* last break char */
- X char tflg; /* 0 = alpha, 1 = numeric */
- X union { /* Resulting value; */
- X int tnum;/* either a #, or */
- X const struct tmwent *ttmw;/* ptr to a tmwent. */
- X } tval;
- X};
- X
- Xstatic const struct tmwent*ptmatchstr P((const char*,int,const struct tmwent*));
- Xstatic int pt12hack P((struct tm *,int));
- Xstatic int ptitoken P((struct token *));
- Xstatic int ptstash P((int *,int));
- Xstatic int pttoken P((struct token *));
- X
- X static int
- Xgoodzone(t, offset, am)
- X register const struct token *t;
- X int offset;
- X int *am;
- X{
- X register int m;
- X if (
- X t->tflg &&
- X t->tcnt == 4+offset &&
- X (m = t->tval.tnum) <= 2400 &&
- X isdigit(t->tcp[offset]) &&
- X (m%=100) < 60
- X ) {
- X m += t->tval.tnum/100 * 60;
- X if (t->tcp[offset-1]=='+')
- X m = -m;
- X *am = m;
- X return 1;
- X }
- X return 0;
- X}
- X
- X int
- Xpartime(astr, atm, zone)
- Xconst char *astr;
- Xregister struct tm *atm;
- Xint *zone;
- X{
- X register int i;
- X struct token btoken, atoken;
- X int zone_offset; /* minutes west of GMT, plus TZ_OFFSET */
- X register const char *cp;
- X register char ch;
- X int ord, midnoon;
- X int *atmfield, dst, m;
- X int got1 = 0;
- X
- X atm->tm_sec = TMNULL;
- X atm->tm_min = TMNULL;
- X atm->tm_hour = TMNULL;
- X atm->tm_mday = TMNULL;
- X atm->tm_mon = TMNULL;
- X atm->tm_year = TMNULL;
- X atm->tm_wday = TMNULL;
- X atm->tm_yday = TMNULL;
- X midnoon = TMNULL; /* and our own temp stuff */
- X zone_offset = TMNULL;
- X dst = TMNULL;
- X btoken.tcnt = btoken.tbrk = 0;
- X btoken.tcp = astr;
- X
- X for (;; got1=1) {
- X if (!ptitoken(&btoken)) /* Get a token */
- X { if(btoken.tval.tnum) return(0); /* Read error? */
- X if (given(midnoon)) /* EOF, wrap up */
- X if (!pt12hack(atm, midnoon))
- X return 0;
- X if (!given(atm->tm_min))
- X atm->tm_min = 0;
- X *zone =
- X (given(zone_offset) ? zone_offset-TZ_OFFSET : 0)
- X - (given(dst) ? dst : 0);
- X return got1;
- X }
- X if(btoken.tflg == 0) /* Alpha? */
- X { i = btoken.tval.ttmw->wval;
- X switch (btoken.tval.ttmw->wtype) {
- X default:
- X return 0;
- X case TM_MON:
- X atmfield = &atm->tm_mon;
- X break;
- X case TM_WDAY:
- X atmfield = &atm->tm_wday;
- X break;
- X case TM_DST:
- X atmfield = &dst;
- X break;
- X case TM_LT:
- X if (ptstash(&dst, 0))
- X return 0;
- X i = 48*60; /* local time magic number -- see maketime() */
- X /* fall into */
- X case TM_ZON:
- X i += TZ_OFFSET;
- X if (btoken.tval.ttmw->wflgs & TWDST)
- X if (ptstash(&dst, 60))
- X return 0;
- X /* Peek ahead for offset immediately afterwards. */
- X if (
- X (btoken.tbrk=='-' || btoken.tbrk=='+') &&
- X (atoken=btoken, ++atoken.tcnt, ptitoken(&atoken)) &&
- X goodzone(&atoken, 0, &m)
- X ) {
- X i += m;
- X btoken = atoken;
- X }
- X atmfield = &zone_offset;
- X break;
- X case TM_12:
- X atmfield = &midnoon;
- X }
- X if (ptstash(atmfield, i))
- X return(0); /* ERR: val already set */
- X continue;
- X }
- X
- X /* Token is number. Lots of hairy heuristics. */
- X if (!isdigit(*btoken.tcp)) {
- X if (!goodzone(&btoken, 1, &m))
- X return 0;
- X zone_offset = TZ_OFFSET + m;
- X continue;
- X }
- X
- X i = btoken.tval.tnum; /* Value now known to be valid; get it. */
- X if (btoken.tcnt == 3) /* 3 digits = HMM */
- X {
- Xhhmm4: if (ptstash(&atm->tm_min, i%100))
- X return(0); /* ERR: min conflict */
- X i /= 100;
- Xhh2: if (ptstash(&atm->tm_hour, i))
- X return(0); /* ERR: hour conflict */
- X continue;
- X }
- X
- X if (4 < btoken.tcnt)
- X goto year4; /* far in the future */
- X if(btoken.tcnt == 4) /* 4 digits = YEAR or HHMM */
- X { if (given(atm->tm_year)) goto hhmm4; /* Already got yr? */
- X if (given(atm->tm_hour)) goto year4; /* Already got hr? */
- X if(btoken.tbrk == ':') /* HHMM:SS ? */
- X if ( ptstash(&atm->tm_hour, i/100)
- X || ptstash(&atm->tm_min, i%100))
- X return(0); /* ERR: hr/min clash */
- X else goto coltm2; /* Go handle SS */
- X if(btoken.tbrk != ',' && btoken.tbrk != '/'
- X && (atoken=btoken, ptitoken(&atoken)) /* Peek */
- X && ( atoken.tflg
- X ? !isdigit(*atoken.tcp)
- X : atoken.tval.ttmw->wflgs & TWTIME)) /* HHMM-ZON */
- X goto hhmm4;
- X goto year4; /* Give up, assume year. */
- X }
- X
- X /* From this point on, assume tcnt == 1 or 2 */
- X /* 2 digits = MM, DD, or HH (MM and SS caught at coltime) */
- X if(btoken.tbrk == ':') /* HH:MM[:SS] */
- X goto coltime; /* must be part of time. */
- X if (31 < i)
- X return 0;
- X
- X /* Check for numerical-format date */
- X for (cp = "/-."; ch = *cp++;)
- X { ord = (ch == '.' ? 0 : 1); /* n/m = D/M or M/D */
- X if(btoken.tbrk == ch) /* "NN-" */
- X { if(btoken.tbrkl != ch)
- X {
- X atoken = btoken;
- X atoken.tcnt++;
- X if (ptitoken(&atoken)
- X && atoken.tflg == 0
- X && atoken.tval.ttmw->wtype == TM_MON)
- X goto dd2;
- X if(ord)goto mm2; else goto dd2; /* "NN-" */
- X } /* "-NN-" */
- X if (!given(atm->tm_mday)
- X && given(atm->tm_year)) /* If "YYYY-NN-" */
- X goto mm2; /* then always MM */
- X if(ord)goto dd2; else goto mm2;
- X }
- X if(btoken.tbrkl == ch /* "-NN" */
- X && given(ord ? atm->tm_mon : atm->tm_mday))
- X if (!given(ord ? atm->tm_mday : atm->tm_mon)) /* MM/DD */
- X if(ord)goto dd2; else goto mm2;
- X }
- X
- X /* Now reduced to choice between HH and DD */
- X if (given(atm->tm_hour)) goto dd2; /* Have hour? Assume day. */
- X if (given(atm->tm_mday)) goto hh2; /* Have day? Assume hour. */
- X if (given(atm->tm_mon)) goto dd2; /* Have month? Assume day. */
- X if(i > 24) goto dd2; /* Impossible HH means DD */
- X atoken = btoken;
- X if (!ptitoken(&atoken)) /* Read ahead! */
- X if(atoken.tval.tnum) return(0); /* ERR: bad token */
- X else goto dd2; /* EOF, assume day. */
- X if ( atoken.tflg
- X ? !isdigit(*atoken.tcp)
- X : atoken.tval.ttmw->wflgs & TWTIME)
- X /* If next token is a time spec, assume hour */
- X goto hh2; /* e.g. "3 PM", "11-EDT" */
- X
- Xdd2: if (ptstash(&atm->tm_mday, i)) /* Store day (1 based) */
- X return(0);
- X continue;
- X
- Xmm2: if (ptstash(&atm->tm_mon, i-1)) /* Store month (make zero based) */
- X return(0);
- X continue;
- X
- Xyear4: if ((i-=1900) < 0 || ptstash(&atm->tm_year, i)) /* Store year-1900 */
- X return(0); /* ERR: year conflict */
- X continue;
- X
- X /* Hack HH:MM[[:]SS] */
- Xcoltime:
- X if (ptstash(&atm->tm_hour, i)) return 0;
- X if (!ptitoken(&btoken))
- X return(!btoken.tval.tnum);
- X if(!btoken.tflg) return(0); /* ERR: HH:<alpha> */
- X if(btoken.tcnt == 4) /* MMSS */
- X if (ptstash(&atm->tm_min, btoken.tval.tnum/100)
- X || ptstash(&atm->tm_sec, btoken.tval.tnum%100))
- X return(0);
- X else continue;
- X if(btoken.tcnt != 2
- X || ptstash(&atm->tm_min, btoken.tval.tnum))
- X return(0); /* ERR: MM bad */
- X if (btoken.tbrk != ':') continue; /* Seconds follow? */
- Xcoltm2: if (!ptitoken(&btoken))
- X return(!btoken.tval.tnum);
- X if(!btoken.tflg || btoken.tcnt != 2 /* Verify SS */
- X || ptstash(&atm->tm_sec, btoken.tval.tnum))
- X return(0); /* ERR: SS bad */
- X }
- X}
- X
- X/* Store date/time value, return 0 if successful.
- X * Fail if entry is already set.
- X */
- X static int
- Xptstash(adr,val)
- Xint *adr;
- Xint val;
- X{ register int *a;
- X if (given(*(a=adr)))
- X return 1;
- X *a = val;
- X return(0);
- X}
- X
- X/* This subroutine is invoked for AM, PM, NOON and MIDNIGHT when wrapping up
- X * just prior to returning from partime.
- X */
- X static int
- Xpt12hack(tm, aval)
- Xregister struct tm *tm;
- Xregister int aval;
- X{ register int h = tm->tm_hour;
- X switch (aval) {
- X case T12_AM:
- X case T12_PM:
- X if (h > 12)
- X return 0;
- X if (h == 12)
- X tm->tm_hour = 0;
- X if (aval == T12_PM)
- X tm->tm_hour += 12;
- X break;
- X default:
- X if (0 < tm->tm_min || 0 < tm->tm_sec)
- X return 0;
- X if (!given(h) || h==12)
- X tm->tm_hour = aval;
- X else if (aval==T12_MIDNIGHT && (h==0 || h==24))
- X return 0;
- X }
- X return 1;
- X}
- X
- X/* Get a token and identify it to some degree.
- X * Returns 0 on failure; token.tval will be 0 for normal EOF, otherwise
- X * hit error of some sort
- X */
- X
- X static int
- Xptitoken(tkp)
- Xregister struct token *tkp;
- X{
- X register const char *cp;
- X register int i, j, k;
- X
- X if (!pttoken(tkp))
- X#ifdef DEBUG
- X {
- X VOID printf("EOF\n");
- X return(0);
- X }
- X#else
- X return(0);
- X#endif
- X cp = tkp->tcp;
- X
- X#ifdef DEBUG
- X VOID printf("Token: \"%.*s\" ", tkp->tcnt, cp);
- X#endif
- X
- X if (tkp->tflg) {
- X i = tkp->tcnt;
- X if (*cp == '+' || *cp == '-') {
- X cp++;
- X i--;
- X }
- X while (0 <= --i) {
- X j = tkp->tval.tnum*10;
- X k = j + (*cp++ - '0');
- X if (j/10 != tkp->tval.tnum || k < j) {
- X /* arithmetic overflow */
- X tkp->tval.tnum = 1;
- X return 0;
- X }
- X tkp->tval.tnum = k;
- X }
- X } else if (!(tkp->tval.ttmw = ptmatchstr(cp, tkp->tcnt, tmwords)))
- X {
- X#ifdef DEBUG
- X VOID printf("Not found!\n");
- X#endif
- X tkp->tval.tnum = 1;
- X return 0;
- X }
- X
- X#ifdef DEBUG
- X if(tkp->tflg)
- X VOID printf("Val: %d.\n",tkp->tval.tnum);
- X else VOID printf("Found: \"%s\", val: %d, type %d\n",
- X tkp->tval.ttmw->went,tkp->tval.ttmw->wval,tkp->tval.ttmw->wtype);
- X#endif
- X
- X return(1);
- X}
- X
- X/* Read token from input string into token structure */
- X static int
- Xpttoken(tkp)
- Xregister struct token *tkp;
- X{
- X register const char *cp;
- X register int c;
- X const char *astr;
- X
- X tkp->tcp = astr = cp = tkp->tcp + tkp->tcnt;
- X tkp->tbrkl = tkp->tbrk; /* Set "last break" */
- X tkp->tcnt = tkp->tbrk = tkp->tflg = 0;
- X tkp->tval.tnum = 0;
- X
- X while(c = *cp++)
- X { switch(c)
- X { case ' ': case '\t': /* Flush all whitespace */
- X case '\r': case '\n':
- X case '\v': case '\f':
- X if (!tkp->tcnt) { /* If no token yet */
- X tkp->tcp = cp; /* ignore the brk */
- X continue; /* and go on. */
- X }
- X /* fall into */
- X case '(': case ')': /* Perhaps any non-alphanum */
- X case '-': case ',': /* shd qualify as break? */
- X case '+':
- X case '/': case ':': case '.': /* Break chars */
- X if(tkp->tcnt == 0) /* If no token yet */
- X { tkp->tcp = cp; /* ignore the brk */
- X tkp->tbrkl = c;
- X continue; /* and go on. */
- X }
- X tkp->tbrk = c;
- X return(tkp->tcnt);
- X }
- X if (!tkp->tcnt++) { /* If first char of token, */
- X if (isdigit(c)) {
- X tkp->tflg = 1;
- X if (astr<cp-2 && (cp[-2]=='-'||cp[-2]=='+')) {
- X /* timezone is break+sign+digit */
- X tkp->tcp--;
- X tkp->tcnt++;
- X }
- X }
- X } else if ((isdigit(c)!=0) != tkp->tflg) { /* else check type */
- X tkp->tbrk = c;
- X return --tkp->tcnt; /* Wrong type, back up */
- X }
- X }
- X return(tkp->tcnt); /* When hit EOF */
- X}
- X
- X
- X static const struct tmwent *
- Xptmatchstr(astr,cnt,astruc)
- X const char *astr;
- X int cnt;
- X const struct tmwent *astruc;
- X{
- X register const char *cp, *mp;
- X register int c;
- X const struct tmwent *lastptr;
- X int i;
- X
- X lastptr = 0;
- X for(;mp = astruc->went; astruc += 1)
- X { cp = astr;
- X for(i = cnt; i > 0; i--)
- X {
- X switch (*cp++ - (c = *mp++))
- X { case 0: continue; /* Exact match */
- X case 'A'-'a':
- X if (ctab[c] == Letter)
- X continue;
- X }
- X break;
- X }
- X if(i==0)
- X if (!*mp) return astruc; /* Exact match */
- X else if(lastptr) return(0); /* Ambiguous */
- X else lastptr = astruc; /* 1st ambig */
- X }
- X return lastptr;
- X}
- END_OF_FILE
- if test 19500 -ne `wc -c <'src/partime.c'`; then
- echo shar: \"'src/partime.c'\" unpacked with wrong size!
- fi
- # end of 'src/partime.c'
- fi
- if test -f 'src/rcssyn.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rcssyn.c'\"
- else
- echo shar: Extracting \"'src/rcssyn.c'\" \(18364 characters\)
- sed "s/^X//" >'src/rcssyn.c' <<'END_OF_FILE'
- X/*
- X * RCS file input
- X */
- X/*********************************************************************************
- X * Syntax Analysis.
- X * Keyword table
- X * Testprogram: define SYNTEST
- X * Compatibility with Release 2: define COMPAT2=1
- X *********************************************************************************
- X */
- X
- X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- X Copyright 1990 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- XThis file is part of RCS.
- X
- XRCS is free software; you can redistribute it and/or modify
- Xit under the terms of the GNU General Public License as published by
- Xthe Free Software Foundation; either version 1, or (at your option)
- Xany later version.
- X
- XRCS is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
- XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- XGNU General Public License for more details.
- X
- XYou should have received a copy of the GNU General Public License
- Xalong with RCS; see the file COPYING. If not, write to
- Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- XReport problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X*/
- X
- X
- X/* $Log: rcssyn.c,v $
- X * Revision 5.4 1990/11/01 05:28:48 eggert
- X * When ignoring unknown phrases, copy them to the output RCS file.
- X * Permit arbitrary data in logs and comment leaders.
- X * Don't check for nontext on initial checkin.
- X *
- X * Revision 5.3 1990/09/20 07:58:32 eggert
- X * Remove the test for non-text bytes; it caused more pain than it cured.
- X *
- X * Revision 5.2 1990/09/04 08:02:30 eggert
- X * Parse RCS files with no revisions.
- X * Don't strip leading white space from diff commands. Count RCS lines better.
- X *
- X * Revision 5.1 1990/08/29 07:14:06 eggert
- X * Add -kkvl. Clean old log messages too.
- X *
- X * Revision 5.0 1990/08/22 08:13:44 eggert
- X * Try to parse future RCS formats without barfing.
- X * Add -k. Don't require final newline.
- X * Remove compile-time limits; use malloc instead.
- X * Don't output branch keyword if there's no default branch,
- X * because RCS version 3 doesn't understand it.
- X * Tune. Remove lint.
- X * Add support for ISO 8859. Ansify and Posixate.
- X * Check that a newly checked-in file is acceptable as input to 'diff'.
- X * Check diff's output.
- X *
- X * Revision 4.6 89/05/01 15:13:32 narten
- X * changed copyright header to reflect current distribution rules
- X *
- X * Revision 4.5 88/08/09 19:13:21 eggert
- X * Allow cc -R; remove lint.
- X *
- X * Revision 4.4 87/12/18 11:46:16 narten
- X * more lint cleanups (Guy Harris)
- X *
- X * Revision 4.3 87/10/18 10:39:36 narten
- X * Updating version numbers. Changes relative to 1.1 actually relative to
- X * 4.1
- X *
- X * Revision 1.3 87/09/24 14:00:49 narten
- X * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- X * warnings)
- X *
- X * Revision 1.2 87/03/27 14:22:40 jenkins
- X * Port to suns
- X *
- X * Revision 4.1 83/03/28 11:38:49 wft
- X * Added parsing and printing of default branch.
- X *
- X * Revision 3.6 83/01/15 17:46:50 wft
- X * Changed readdelta() to initialize selector and log-pointer.
- X * Changed puttree to check for selector==DELETE; putdtext() uses DELNUMFORM.
- X *
- X * Revision 3.5 82/12/08 21:58:58 wft
- X * renamed Commentleader to Commleader.
- X *
- X * Revision 3.4 82/12/04 13:24:40 wft
- X * Added routine gettree(), which updates keeplock after reading the
- X * delta tree.
- X *
- X * Revision 3.3 82/11/28 21:30:11 wft
- X * Reading and printing of Suffix removed; version COMPAT2 skips the
- X * Suffix for files of release 2 format. Fixed problems with printing nil.
- X *
- X * Revision 3.2 82/10/18 21:18:25 wft
- X * renamed putdeltatext to putdtext.
- X *
- X * Revision 3.1 82/10/11 19:45:11 wft
- X * made sure getc() returns into an integer.
- X */
- X
- X
- X
- X/* version COMPAT2 reads files of the format of release 2 and 3, but
- X * generates files of release 3 format. Need not be defined if no
- X * old RCS files generated with release 2 exist.
- X */
- X/* version SYNTEST inputs a RCS file and then prints out its internal
- X * data structures.
- X*/
- X
- X#include "rcsbase.h"
- X
- XlibId(synId, "$Id: rcssyn.c,v 5.4 1990/11/01 05:28:48 eggert Exp $")
- X
- X/* forward */
- Xstatic const char *getkeyval P((const char*,enum tokens,int));
- X
- X/* keyword table */
- X
- Xconst char
- X Kdesc[] = "desc",
- X Klog[] = "log",
- X Ktext[] = "text";
- X
- Xstatic const char
- X Kaccess[] = "access",
- X Kauthor[] = "author",
- X Kbranch[] = "branch",
- X Kbranches[] = "branches",
- X Kcomment[] = "comment",
- X Kdate[] = "date",
- X Kexpand[] = "expand",
- X Khead[] = "head",
- X Klocks[] = "locks",
- X Knext[] = "next",
- X Kstate[] = "state",
- X Kstrict[] = "strict",
- X#if COMPAT2
- X Ksuffix[] = "suffix",
- X#endif
- X Ksymbols[] = "symbols";
- X
- Xstatic struct buf Commleader;
- Xstatic struct cbuf Ignored;
- Xstruct cbuf Comment;
- Xstruct access * AccessList;
- Xstruct assoc * Symbols;
- Xstruct lock * Locks;
- Xint Expand;
- Xint StrictLocks;
- Xstruct hshentry * Head;
- Xconst char * Dbranch;
- Xint TotalDeltas;
- X
- X
- X static void
- Xgetsemi(key)
- X const char *key;
- X/* Get a semicolon to finish off a phrase started by KEY. */
- X{
- X if (!getlex(SEMI))
- X fatserror("missing ';' after '%s'", key);
- X}
- X
- X static struct hshentry *
- Xgetdnum()
- X/* Get a delta number. */
- X{
- X register struct hshentry *delta = getnum();
- X if (delta && countnumflds(delta->num)&1)
- X fatserror("%s isn't a delta number", delta->num);
- X return delta;
- X}
- X
- X
- X void
- Xgetadmin()
- X/* Read an <admin> and initialize the appropriate global variables. */
- X{
- X register const char *id;
- X struct access * newaccess;
- X struct assoc * newassoc;
- X struct lock * newlock;
- X struct hshentry * delta;
- X struct access **LastAccess;
- X struct assoc **LastSymbol;
- X struct lock **LastLock;
- X struct buf b;
- X struct cbuf cb;
- X
- X TotalDeltas=0;
- X
- X getkey(Khead);
- X Head = getdnum();
- X getsemi(Khead);
- X
- X Dbranch = nil;
- X if (getkeyopt(Kbranch)) {
- X if ((delta = getnum()))
- X Dbranch = delta->num;
- X getsemi(Kbranch);
- X }
- X
- X
- X#if COMPAT2
- X /* read suffix. Only in release 2 format */
- X if (getkeyopt(Ksuffix)) {
- X if (nexttok==STRING) {
- X readstring(); nextlex(); /* Throw away the suffix. */
- X } else if (nexttok==ID) {
- X nextlex();
- X }
- X getsemi(Ksuffix);
- X }
- X#endif
- X
- X getkey(Kaccess);
- X LastAccess = &AccessList;
- X while (id=getid()) {
- X newaccess = ftalloc(struct access);
- X newaccess->login = id;
- X *LastAccess = newaccess;
- X LastAccess = &newaccess->nextaccess;
- X }
- X *LastAccess = nil;
- X getsemi(Kaccess);
- X
- X getkey(Ksymbols);
- X LastSymbol = &Symbols;
- X while (id = getid()) {
- X if (!getlex(COLON))
- X fatserror("missing ':' in symbolic name definition");
- X if (!(delta=getnum())) {
- X fatserror("missing number in symbolic name definition");
- X } else { /*add new pair to association list*/
- X newassoc = ftalloc(struct assoc);
- X newassoc->symbol=id;
- X newassoc->num = delta->num;
- X *LastSymbol = newassoc;
- X LastSymbol = &newassoc->nextassoc;
- X }
- X }
- X *LastSymbol = nil;
- X getsemi(Ksymbols);
- X
- X getkey(Klocks);
- X LastLock = &Locks;
- X while (id = getid()) {
- X if (!getlex(COLON))
- X fatserror("missing ':' in lock");
- X if (!(delta=getdnum())) {
- X fatserror("missing number in lock");
- X } else { /*add new pair to lock list*/
- X newlock = ftalloc(struct lock);
- X newlock->login=id;
- X newlock->delta=delta;
- X *LastLock = newlock;
- X LastLock = &newlock->nextlock;
- X }
- X }
- X *LastLock = nil;
- X getsemi(Klocks);
- X
- X if ((StrictLocks = getkeyopt(Kstrict)))
- X getsemi(Kstrict);
- X
- X Comment.size = 0;
- X if (getkeyopt(Kcomment)) {
- X if (nexttok==STRING) {
- X Comment = savestring(&Commleader);
- X nextlex();
- X }
- X getsemi(Kcomment);
- X }
- X
- X Expand = KEYVAL_EXPAND;
- X if (getkeyopt(Kexpand)) {
- X if (nexttok==STRING) {
- X bufautobegin(&b);
- X cb = savestring(&b);
- X if ((Expand = str2expmode(cb.string)) < 0)
- X fatserror("unknown expand mode %s", b.string);
- X bufautoend(&b);
- X nextlex();
- X }
- X getsemi(Kexpand);
- X }
- X Ignored = getphrases(Kdesc);
- X}
- X
- Xconst char *const expand_names[] = {
- X /* These must agree with *_EXPAND in rcsbase.h. */
- X "kv","kvl","k","v","o",
- X 0
- X};
- X
- X int
- Xstr2expmode(s)
- X const char *s;
- X/* Yield expand mode corresponding to S, or -1 if bad. */
- X{
- X const char *const *p;
- X
- X for (p = expand_names; *p; ++p)
- X if (strcmp(*p,s) == 0)
- X return p - expand_names;
- X return -1;
- X}
- X
- X
- X void
- Xignorephrase()
- X/* Ignore a phrase introduced by a later version of RCS. */
- X{
- X warnignore();
- X hshenter=false;
- X for (;;) {
- X switch (nexttok) {
- X case SEMI: hshenter=true; nextlex(); return;
- X case ID:
- X case NUM: ffree1(NextString); break;
- X case STRING: readstring(); break;
- X default: break;
- X }
- X nextlex();
- X }
- X}
- X
- X
- X static int
- Xgetdelta()
- X/* Function: reads a delta block.
- X * returns false if the current block does not start with a number.
- X */
- X{
- X register struct hshentry * Delta, * num;
- X struct branchhead **LastBranch, *NewBranch;
- X
- X if (!(Delta = getdnum()))
- X return false;
- X
- X hshenter = false; /*Don't enter dates into hashtable*/
- X Delta->date = getkeyval(Kdate, NUM, false);
- X hshenter=true; /*reset hshenter for revision numbers.*/
- X
- X Delta->author = getkeyval(Kauthor, ID, false);
- X
- X Delta->state = getkeyval(Kstate, ID, true);
- X
- X getkey(Kbranches);
- X LastBranch = &Delta->branches;
- X while ((num = getdnum())) {
- X NewBranch = ftalloc(struct branchhead);
- X NewBranch->hsh = num;
- X *LastBranch = NewBranch;
- X LastBranch = &NewBranch->nextbranch;
- X }
- X *LastBranch = nil;
- X getsemi(Kbranches);
- X
- X getkey(Knext);
- X Delta->next = num = getdnum();
- X getsemi(Knext);
- X Delta->lockedby = nil;
- X Delta->selector = true;
- X Delta->ig = getphrases(Kdesc);
- X TotalDeltas++;
- X return (true);
- X}
- X
- X
- X void
- Xgettree()
- X/* Function: Reads in the delta tree with getdelta(), then
- X * updates the lockedby fields.
- X */
- X{
- X const struct lock *currlock;
- X
- X while (getdelta());
- X currlock=Locks;
- X while (currlock) {
- X currlock->delta->lockedby = currlock->login;
- X currlock = currlock->nextlock;
- X }
- X}
- X
- X
- X void
- Xgetdesc(prdesc)
- Xint prdesc;
- X/* Function: read in descriptive text
- X * nexttok is not advanced afterwards.
- X * If prdesc is set, the text is printed to stdout.
- X */
- X{
- X
- X getkeystring(Kdesc);
- X if (prdesc)
- X printstring(); /*echo string*/
- X else readstring(); /*skip string*/
- X}
- X
- X
- X
- X
- X
- X
- X static const char *
- Xgetkeyval(keyword, token, optional)
- X const char *keyword;
- X enum tokens token;
- X int optional;
- X/* reads a pair of the form
- X * <keyword> <token> ;
- X * where token is one of <id> or <num>. optional indicates whether
- X * <token> is optional. A pointer to
- X * the actual character string of <id> or <num> is returned.
- X */
- X{
- X register const char *val = nil;
- X
- X getkey(keyword);
- X if (nexttok==token) {
- X val = NextString;
- X nextlex();
- X } else {
- X if (!optional)
- X fatserror("missing %s", keyword);
- X }
- X getsemi(keyword);
- X return(val);
- X}
- X
- X
- X
- X
- X void
- Xputadmin(fout)
- Xregister FILE * fout;
- X/* Function: Print the <admin> node read with getadmin() to file fout.
- X * Assumption: Variables AccessList, Symbols, Locks, StrictLocks,
- X * and Head have been set.
- X */
- X{
- X const struct assoc *curassoc;
- X const struct lock *curlock;
- X const struct access *curaccess;
- X register const char *sp;
- X register size_t ss;
- X
- X aprintf(fout, "%s\t%s;\n", Khead, Head?Head->num:"");
- X if (Dbranch && VERSION(4)<=RCSversion)
- X aprintf(fout, "%s\t%s;\n", Kbranch, Dbranch);
- X
- X aputs(Kaccess, fout);
- X curaccess = AccessList;
- X while (curaccess) {
- X aprintf(fout, "\n\t%s", curaccess->login);
- X curaccess = curaccess->nextaccess;
- X }
- X aprintf(fout, ";\n%s", Ksymbols);
- X curassoc = Symbols;
- X while (curassoc) {
- X aprintf(fout, "\n\t%s:%s", curassoc->symbol, curassoc->num);
- X curassoc = curassoc->nextassoc;
- X }
- X aprintf(fout, ";\n%s", Klocks);
- X curlock = Locks;
- X while (curlock) {
- X aprintf(fout, "\n\t%s:%s", curlock->login, curlock->delta->num);
- X curlock = curlock->nextlock;
- X }
- X if (StrictLocks) aprintf(fout, "; %s", Kstrict);
- X aprintf(fout, ";\n");
- X if ((ss = Comment.size)) {
- X aprintf(fout, "%s\t%c", Kcomment, SDELIM);
- X sp = Comment.string;
- X do {
- X if (*sp == SDELIM)
- X afputc(SDELIM,fout);
- X afputc(*sp++,fout);
- X } while (--ss);
- X aprintf(fout, "%c;\n", SDELIM);
- X }
- X if (Expand != KEYVAL_EXPAND)
- X aprintf(fout, "%s\t%c%s%c;\n",
- X Kexpand, SDELIM, expand_names[Expand], SDELIM
- X );
- X awrite(Ignored.string, Ignored.size, fout);
- X aputc('\n', fout);
- X}
- X
- X
- X
- X
- X static void
- Xputdelta(node,fout)
- Xregister const struct hshentry *node;
- Xregister FILE * fout;
- X/* Function: prints a <delta> node to fout;
- X */
- X{
- X const struct branchhead *nextbranch;
- X
- X if (node == nil) return;
- X
- X aprintf(fout, "\n%s\n%s\t%s;\t%s %s;\t%s %s;\nbranches",
- X node->num,
- X Kdate, node->date,
- X Kauthor, node->author,
- X Kstate, node->state?node->state:""
- X );
- X nextbranch = node->branches;
- X while (nextbranch) {
- X aprintf(fout, "\n\t%s", nextbranch->hsh->num);
- X nextbranch = nextbranch->nextbranch;
- X }
- X
- X aprintf(fout, ";\n%s\t%s;\n", Knext, node->next?node->next->num:"");
- X awrite(node->ig.string, node->ig.size, fout);
- X}
- X
- X
- X
- X
- X void
- Xputtree(root,fout)
- Xconst struct hshentry * root;
- Xregister FILE * fout;
- X/* Function: prints the delta tree in preorder to fout, starting with root.
- X */
- X{
- X const struct branchhead *nextbranch;
- X
- X if (root==nil) return;
- X
- X if (root->selector)
- X putdelta(root,fout);
- X
- X puttree(root->next,fout);
- X
- X nextbranch = root->branches;
- X while (nextbranch) {
- X puttree(nextbranch->hsh,fout);
- X nextbranch = nextbranch->nextbranch;
- X }
- X}
- X
- X
- X
- Xint putdtext(num,log,srcfilename,fout,diffmt)
- X const char *num, *srcfilename;
- X struct cbuf log;
- X FILE *fout;
- X int diffmt;
- X/* Function: write a deltatext-node to fout.
- X * num points to the deltanumber, log to the logmessage, and
- X * sourcefile contains the text. Doubles up all SDELIMs in both the
- X * log and the text; Makes sure the log message ends in \n.
- X * returns false on error.
- X * If diffmt is true, also checks that text is valid diff -n output.
- X */
- X{
- X FILE *fin;
- X int result;
- X if (!(fin = fopen(srcfilename,"r"))) {
- X eerror(srcfilename);
- X return false;
- X }
- X result = putdftext(num,log,fin,fout,diffmt);
- X ffclose(fin);
- X return result;
- X}
- X
- X int
- Xputdftext(num,log,fin,fout,diffmt)
- X const char *num;
- X struct cbuf log;
- X register FILE *fin;
- X register FILE *fout;
- X int diffmt;
- X/* like putdtext(), except the source file is already open */
- X{
- X register const char *sp;
- X register int c;
- X register size_t ss;
- X int ed;
- X struct diffcmd dc;
- X
- X aprintf(fout,DELNUMFORM,num,Klog);
- X /* put log */
- X afputc(SDELIM,fout);
- X sp = log.string;
- X for (ss = log.size; ss; --ss) {
- X if (*sp == SDELIM)
- X aputc(SDELIM,fout);
- X aputc(*sp++,fout);
- X }
- X /* put text */
- X aprintf(fout, "\n%c\n%s\n%c",SDELIM,Ktext,SDELIM);
- X if (!diffmt) {
- X /* Copy the file */
- X while ((c=getc(fin))!=EOF) {
- X if (c==SDELIM) aputc(SDELIM,fout); /*double up SDELIM*/
- X aputc(c,fout);
- X }
- X } else {
- X initdiffcmd(&dc);
- X while (0 <= (ed = getdiffcmd(fin,EOF,fout,&dc)))
- X if (ed)
- X while (dc.nlines--)
- X do {
- X if ((c=getc(fin)) == EOF) {
- X if (!dc.nlines)
- X goto OK_EOF;
- X faterror("unexpected EOF in diff output");
- X }
- X if (c==SDELIM) aputc(SDELIM,fout);
- X aputc(c,fout);
- X } while (c != '\n');
- X }
- X OK_EOF:
- X aprintf(fout, "%c\n", SDELIM);
- X return true;
- X}
- X
- X void
- Xinitdiffcmd(dc)
- X register struct diffcmd *dc;
- X/* Initialize *dc suitably for getdiffcmd(). */
- X{
- X dc->adprev = 0;
- X dc->dafter = 0;
- X}
- X
- X int
- Xgetdiffcmd(fin,delimiter,fout,dc)
- X register FILE *fin, *fout;
- X int delimiter;
- X struct diffcmd *dc;
- X/* Get a editing command output by 'diff -n' from fin.
- X * The input is delimited by the delimiter, which may be EOF for no delimiter.
- X * Copy a clean version of the command to fout (if nonnull).
- X * Yield 0 for 'd', 1 for 'a', and -1 for EOF.
- X * Store the command's line number and length into dc->line1 and dc->nlines.
- X * Keep dc->adprev and dc->dafter up to date.
- X */
- X{
- X register int c;
- X register char *p;
- X unsigned long line1, nlines;
- X char buf[BUFSIZ];
- X c = getc(fin);
- X if (c==delimiter) {
- X if (c!=EOF && fout)
- X aputc(c, fout);
- X return EOF;
- X }
- X p = buf;
- X do {
- X if (c == EOF) {
- X faterror("unexpected EOF in diff output");
- X }
- X if (buf+BUFSIZ-2 <= p) {
- X faterror("diff output command line too long");
- X }
- X *p++ = c;
- X } while ((c=getc(fin)) != '\n');
- X if (delimiter!=EOF)
- X ++rcsline;
- X *p = '\0';
- X for (p = buf+1; *p++ == ' ';)
- X ;
- X --p;
- X if (!((buf[0]=='a' || buf[0]=='d') && isdigit(*p))) {
- X faterror("bad diff output: %s", buf);
- X }
- X line1 = 0;
- X do {
- X line1 = line1*10 + (*p++ - '0');
- X } while (isdigit(*p));
- X while (*p++ == ' ')
- X ;
- X --p;
- X nlines = 0;
- X while (isdigit(*p))
- X nlines = nlines*10 + (*p++ - '0');
- X if (!nlines) {
- X faterror("incorrect range %lu in diff output: %s", nlines, buf);
- X }
- X switch (buf[0]) {
- X case 'a':
- X if (line1 < dc->adprev) {
- X faterror("backward insertion in diff output: %s", buf);
- X }
- X dc->adprev = line1 + 1;
- X break;
- X case 'd':
- X if (line1 < dc->adprev || line1 < dc->dafter) {
- X faterror("backward deletion in diff output: %s", buf);
- X }
- X dc->adprev = line1;
- X dc->dafter = line1 + nlines;
- X break;
- X }
- X if (fout) {
- X aprintf(fout, "%s\n", buf);
- X }
- X dc->line1 = line1;
- X dc->nlines = nlines;
- X return buf[0] == 'a';
- X}
- X
- X
- X
- X#ifdef SYNTEST
- X
- Xconst char cmdid[] = "syntest";
- X
- X int
- Xmain(argc,argv)
- Xint argc; char * argv[];
- X{
- X
- X if (argc<2) {
- X aputs("No input file\n",stderr);
- X exitmain(EXIT_FAILURE);
- X }
- X if ((finptr=fopen(argv[1], "r")) == NULL) {
- X faterror("can't open input file %s", argv[1]);
- X }
- X Lexinit();
- X getadmin();
- X putadmin(stdout);
- X
- X gettree();
- X puttree(Head,stdout);
- X
- X getdesc(true);
- X
- X if (nextlex(),nexttok!=EOFILE) {
- X fatserror("expecting EOF");
- X }
- X exitmain(EXIT_SUCCESS);
- X}
- X
- X
- Xexiting void exiterr() { _exit(EXIT_FAILURE); }
- X
- X
- X#endif
- X
- END_OF_FILE
- if test 18364 -ne `wc -c <'src/rcssyn.c'`; then
- echo shar: \"'src/rcssyn.c'\" unpacked with wrong size!
- fi
- # end of 'src/rcssyn.c'
- fi
- echo shar: End of archive 8 \(of 12\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-